home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
AX_MBX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-07
|
33KB
|
1,395 lines
/* ax.25 mailbox by w9nk */
/* adapted to CHLNET environment by PE1CHL */
/* outbound forwarding to AX.25 BBS systems added by PE1CHL */
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#ifdef UNIX
#include <sys/types.h>
#endif
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "iface.h"
#include "lapb.h"
#include "smtp.h"
#include "ax_mbx.h"
#include "cmdparse.h"
/* #define MBDEBUG */
static char mbmenu[] = "(B)ye, (I)nfo, (S)end >\r";
static char mbprompt[] = ">\r";
static char mbok[] = "OK\r";
static char mbno[] = "NO\r";
static char mberr[] = "Huh?\r";
static char mbserr[] = "S command syntax error - format is:\r S name [@ host] [< from_addr] [$bulletin_id]\r";
static char mbbaduser[] = "Bad user or host name\r";
static char mbsubject[] = "Subject:\r";
static char mbmesg[] = "Enter message. Terminate with /EX or ^Z in first column:\r";
static char mbtemp[] = "Can't create temp file for mail\r";
static char mbqerr[] = "Couldn't queue message for delivery\r";
static char mbbye[] = "Goodbye!\r";
static char mbcr[] = "\r";
extern char hostname[];
char mbxinfofile[80] = "";
static struct mbx *fwdmbx; /* currently-connecting mbx */
static int mbx_line(),mbx_sid(),mbx_script();
static void mbx_rx(),mbx_tx(),mbx_send(),mbx_doscript();
void mbxfwd();
static int dombxconnect();
struct cmds fwdcmds[] = {
"connect", dombxconnect, 3, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0, NULLCHAR, NULLCHAR
};
extern char *getnenv();
extern char *strstr();
/* find mbx struct for specified axp */
static struct mbx *
find_mbx(axp)
register struct ax25_cb *axp;
{
register struct mbx *m;
for (m = (struct mbx *) ((struct ax25_call *) axp->user)->user;
m != NULLMBX; m = m->next) {
if(m->ax25_cb == axp)
break;
}
return m;
}
/* State-change upcall handler for mailbox */
void
mbx_state(axp,old,new,msg)
register struct ax25_cb *axp;
int old,new,msg;
{
register struct mbx *m;
char *cp;
struct mbxpath *mbp;
char mesg[160];
switch (new)
{
case CONNECTED:
#ifdef MBDEBUG
printf("MBX: connected\n");
#endif
/* check if station already known, and register if not */
if((m = find_mbx(axp)) == NULLMBX) {
if((m = (struct mbx *) calloc(1,sizeof(struct mbx))) == NULLMBX) {
axp->state = DISCONNECTED; /* send DM */
return;
}
/* connect the user to this mbox's user list */
if((m->next = (struct mbx *) ((struct ax25_call *) axp->user)->user)
!= NULLMBX)
m->next->prev = m;
((struct ax25_call *) axp->user)->user = (char *) m;
m->ax25_cb = axp;
pax25(m->name,&axp->addr.dest);
cp = index(m->name,'-');
if (cp != NULLCHAR) /* get rid of SSID */
*cp = '\0';
for (cp = m->name; *cp != '\0'; cp++)
*cp = tolower(*cp); /* convert to lowercase */
axp->r_upcall = mbx_rx;
axp->t_upcall = mbx_tx;
#ifdef MBDEBUG
printf("MBX: new user %s\n",m->name);
#endif
log_ax(axp,"Conn to mbox");
sprintf(mesg,"%c[NET-$]\rWelcome to the %s TCP/IP Mailbox\r%s",
PID_FIRST|PID_LAST|PID_NO_L3,hostname,mbmenu);
enqueue(&axp->txq,qstring(mesg));
}
/* send first message when script starts with "s" */
if (m->state == MBX_CONN)
mbx_tx(axp,1);
break;
case DISCONNECTED:
if ((m = find_mbx(axp)) == NULLMBX)
break;
if(m->prev != NULLMBX)
m->prev->next = m->next;
else
((struct ax25_call *) axp->user)->user = (char *) m->next;
if(m->next != NULLMBX)
m->next->prev = m->prev;
if (m->to != NULLCHAR)
free(m->to);
if (m->tofrom != NULLCHAR)
free(m->tofrom);
if (m->tomsgid != NULLCHAR)
free(m->tomsgid);
if (m->fullfrom != NULLCHAR)
free(m->fullfrom);
if (m->subject != NULLCHAR)
free(m->subject);
while (m->mbpath != NULLMBXPATH) {
mbp = m->mbpath->next;
free(m->mbpath);
m->mbpath = mbp;
}
if (m->tfile != NULLFILE)
fclose(m->tfile);
if (m->script != NULLFILE)
fclose(m->script);
if (m->smtp_cb != NULLCB)
if (m->state == MBX_DISC) { /* expecting DISC? */
#ifdef MBDEBUG
printf("MBX: mbx_state calls mbxfwd\n");
#endif
mbxfwd(m->smtp_cb); /* then, start fwd to next box */
} else {
#ifdef MBDEBUG
printf("MBX: mbx_state calls del_session\n");
#endif
del_session(m->smtp_cb); /* no, wait a while */
}
free(m);
break;
}
}
/* receive upcall for ax.25 */
static void mbx_rx(axp,cnt)
struct ax25_cb *axp;
int16 cnt;
{
struct mbx *m;
struct mbuf *bp;
char line[MBXLINE + 1];
struct mbuf *recvl_ax25();
if((m = find_mbx(axp)) == NULLMBX) {
disc_ax25(axp); /* who are you?? */
return;
}
while((bp = recvl_ax25(axp,0)) != NULLBUF){ /* get a line of text */
line[pullup(&bp,line,sizeof(line) - 1)] = '\0';
rip(line);
free_p(bp);
if(mbx_line(m,line) == -1) /* evaluate inputline */
break; /* quit after "bye" */
}
}
/* transmit upcall (used to send a file/mail) */
static void
mbx_tx(axp,cnt)
struct ax25_cb *axp;
int16 cnt;
{
struct mbx *m;
int remain;
char *pac;
char line[MBXLINE + 1];
if((m = find_mbx(axp)) == NULLMBX) {
disc_ax25(axp); /* who are you?? */
return;
}
switch (m->state)
{
case MBX_CONN: /* connecting? */
case MBX_SEND: /* transferring mail? */
mbx_doscript(m); /* keep it going */
break;
case MBX_INFO: /* sending info? */
case MBX_BODY: /* sending mail body? */
if (m->tfile != NULLFILE) {
if ((remain = axp->maxframe - len_q(axp->txq)) < 2)
pac = NULLCHAR;
else
if ((pac = malloc(axp->paclen)) != NULLCHAR)
pac[0] = '\0'; /* clean packet buffer */
while (fgets(line,sizeof(line),m->tfile) != NULLCHAR) {
rip(line);
strcat(line,mbcr);
if (pac == NULLCHAR) {
mbx_msg(m,line);
remain--;
} else {
if ((strlen(pac) + strlen(line)) < axp->paclen){
strcat(pac,line); /* still fits, concat it */
continue; /* read next line */
}
if (pac[0] != '\0'){
mbx_msg(m,pac); /* too long, flush old */
remain--;
}
strcpy(pac,line);
}
/* when only one packet left in window, stop buffering */
if (remain < 2 && pac != NULLCHAR){
if (pac[0] != '\0'){
mbx_msg(m,pac);
remain--;
}
free(pac);
pac = NULLCHAR;
}
if (remain <= 0)
return; /* window full, pause */
}
fclose(m->tfile);
m->tfile = NULLFILE;
/* don't forget buffered packet */
if (pac != NULLCHAR){
if (pac[0] != '\0')
mbx_msg(m,pac);
free(pac);
}
/* got EOF, see what to do next. when INFO: ->command state */
/* when BODY: send end-of-message and back to SEND state */
if (m->state == MBX_INFO) {
m->state = MBX_CMD;
mbx_msg(m,(m->sid & MBX_SID) ? mbprompt : mbmenu);
} else {
m->state = MBX_SEND;
if (m->sline[1] == '\0')
strcpy(m->sline + 1,"\032"); /* default ^Z */
strcat(m->sline,mbcr);
mbx_msg(m,m->sline + 1);
if (mbx_script(m) == 0)
mbx_doscript(m);
}
}
break;
}
}
/* process one line for the mailbox */
static int
mbx_line(m,line)
struct mbx *m;
char *line;
{
switch (m->state)
{
case MBX_CMD:
switch (tolower(line[0])) {
case 'b': /* bye - bye */
if (!(m->sid & MBX_SID))
mbx_msg(m,mbbye);
close_ax25(m->ax25_cb);
return -1; /* tell line processor to quit */
case 'i': { /* info */
if (mbxinfofile[0] == '\0' ||
(m->tfile = fopen(mbxinfofile,"r")) == NULLFILE)
mbx_msg(m,(m->sid & MBX_SID) ? mbprompt : mbmenu);
else {
m->state = MBX_INFO;
mbx_tx(m->ax25_cb,1);
}
}
break;
case 's': {
int badsubj = 0;
/* Get S-command type (B,P,T, etc.) */
if (line[1] == '\0')
m->stype = ' ';
else
m->stype = toupper(line[1]);
if (mbx_to(m,line) == -1) {
if (m->sid & MBX_SID)
mbx_msg(m,mb